#include "Rp2StandardMesh.h"

using namespace Rp2;

//---------------------------------------------------------------------------------------------------
StandardMesh::StandardMesh(const Attributes& rkAttr,const Transformation* pkTransform)
	:
	m_kAttr(rkAttr)
{
	m_pkVBuffer = 0;
	m_pkIBuffer = 0;
	m_afData = 0;
	if (pkTransform)
	{
		m_kXFrm = *pkTransform;
	}
}
//---------------------------------------------------------------------------------------------------
StandardMesh::~StandardMesh()
{
}
//---------------------------------------------------------------------------------------------------
TriMesh* StandardMesh::Cube(float fRadius)
{
	// create a cube for cube map
	m_pkVBuffer = new VertexBuffer(m_kAttr, 36);
	m_pkIBuffer = new IndexBuffer(36);
	bool bHasNormal = m_kAttr.HasNormal();
	bool bHasTCoord = m_kAttr.HasTCoord(0);

	// bottom of cube
	m_pkVBuffer->Position3(0) = Vector3f(-fRadius, -fRadius, -fRadius);
	m_pkVBuffer->Position3(1) = Vector3f(fRadius, -fRadius, -fRadius);
	m_pkVBuffer->Position3(2) = Vector3f(fRadius, -fRadius, fRadius);
	m_pkVBuffer->Position3(3) = Vector3f(-fRadius, -fRadius, fRadius);
	m_pkVBuffer->Position3(4) = Vector3f(-fRadius, -fRadius, -fRadius);
	m_pkVBuffer->Position3(5) = Vector3f(fRadius, -fRadius, fRadius);
	if (bHasNormal)
	{
		for (int i = 0; i < 6; i++)
		{
			m_pkVBuffer->Normal3(i) = Vector3f(0.0f, -1.0f, 0.0f);
		}
	}
	if (bHasTCoord)
	{
		m_pkVBuffer->TCoord2(0,0) = Vector2f(0.0f, 0.0f);
		m_pkVBuffer->TCoord2(0,1) = Vector2f(fRadius, 0.0f);
		m_pkVBuffer->TCoord2(0,2) = Vector2f(fRadius, fRadius);
		m_pkVBuffer->TCoord2(0,3) = Vector2f(0.0f, fRadius);
		m_pkVBuffer->TCoord2(0,4) = Vector2f(0.0f, 0.0f);
		m_pkVBuffer->TCoord2(0,5) = Vector2f(fRadius, fRadius);
	}

	// top of cube
	m_pkVBuffer->Position3(6) = Vector3f(fRadius, fRadius, fRadius);
	m_pkVBuffer->Position3(7) = Vector3f(fRadius, fRadius, -fRadius);
	m_pkVBuffer->Position3(8) = Vector3f(-fRadius, fRadius, -fRadius);
	m_pkVBuffer->Position3(9) = Vector3f(fRadius, fRadius, fRadius);
	m_pkVBuffer->Position3(10) = Vector3f(-fRadius, fRadius, -fRadius);
	m_pkVBuffer->Position3(11) = Vector3f(-fRadius, fRadius, fRadius);
	if (bHasNormal)
	{
		for (int i = 6; i < 12; i++)
		{
			m_pkVBuffer->Normal3(i) = Vector3f(0.0f, 1.0f, 0.0f);
		}
	}
	if (bHasTCoord)
	{
		m_pkVBuffer->TCoord2(0,6) = Vector2f(fRadius, fRadius);
		m_pkVBuffer->TCoord2(0,7) = Vector2f(fRadius, 0.0f);
		m_pkVBuffer->TCoord2(0,8) = Vector2f(0.0f, 0.0f);
		m_pkVBuffer->TCoord2(0,9) = Vector2f(fRadius, fRadius);
		m_pkVBuffer->TCoord2(0,10) = Vector2f(0.0f, 0.0f);
		m_pkVBuffer->TCoord2(0,11) = Vector2f(0.0f , fRadius);
	}

	// left side
	m_pkVBuffer->Position3(12) = Vector3f(-fRadius, fRadius, fRadius);
	m_pkVBuffer->Position3(13) = Vector3f(-fRadius, fRadius, -fRadius);
	m_pkVBuffer->Position3(14) = Vector3f(-fRadius, -fRadius, -fRadius);
	m_pkVBuffer->Position3(15) = Vector3f(-fRadius, fRadius, fRadius);
	m_pkVBuffer->Position3(16) = Vector3f(-fRadius, -fRadius, -fRadius);
	m_pkVBuffer->Position3(17) = Vector3f(-fRadius, -fRadius, fRadius);
	if (bHasNormal)
	{
		for (int i = 12; i < 18; i++)
		{
			m_pkVBuffer->Normal3(i) = Vector3f(-1.0f, 0.0f, 0.0f);
		}
	}
	if (bHasTCoord)
	{
		m_pkVBuffer->TCoord2(0,12) = Vector2f(fRadius, fRadius);
		m_pkVBuffer->TCoord2(0,13) = Vector2f(fRadius, 0.0f);
		m_pkVBuffer->TCoord2(0,14) = Vector2f(0.0f, 0.0f);
		m_pkVBuffer->TCoord2(0,15) = Vector2f(fRadius, fRadius);
		m_pkVBuffer->TCoord2(0,16) = Vector2f(0.0f, 0.0f);
		m_pkVBuffer->TCoord2(0,17) = Vector2f(0.0f , fRadius);
	}

	// right side
	m_pkVBuffer->Position3(18) = Vector3f(fRadius, -fRadius, -fRadius);
	m_pkVBuffer->Position3(19) = Vector3f(fRadius, fRadius, -fRadius);
	m_pkVBuffer->Position3(20) = Vector3f(fRadius, fRadius, fRadius);
	m_pkVBuffer->Position3(21) = Vector3f(fRadius, fRadius, fRadius);
	m_pkVBuffer->Position3(22) = Vector3f(fRadius, -fRadius, fRadius);
	m_pkVBuffer->Position3(23) = Vector3f(fRadius, -fRadius, -fRadius);
	if (bHasNormal)
	{
		for (int i = 18; i < 24; i++)
		{
			m_pkVBuffer->Normal3(i) = Vector3f(1.0f, 0.0f, 0.0f);
		}
	}
	if (bHasTCoord)
	{
		m_pkVBuffer->TCoord2(0,18) = Vector2f(0.0f, 0.0f);
		m_pkVBuffer->TCoord2(0,19) = Vector2f(fRadius, 0.0f);
		m_pkVBuffer->TCoord2(0,20) = Vector2f(fRadius, fRadius);
		m_pkVBuffer->TCoord2(0,21) = Vector2f(fRadius, fRadius);
		m_pkVBuffer->TCoord2(0,22) = Vector2f(0.0f, fRadius);
		m_pkVBuffer->TCoord2(0,23) = Vector2f(0.0f, 0.0f);
	}	

	//front
	m_pkVBuffer->Position3(24) = Vector3f(fRadius, -fRadius, fRadius);
	m_pkVBuffer->Position3(25) = Vector3f(fRadius, fRadius, fRadius);
	m_pkVBuffer->Position3(26) = Vector3f(-fRadius, fRadius, fRadius);
	m_pkVBuffer->Position3(27) = Vector3f(-fRadius, fRadius, fRadius);
	m_pkVBuffer->Position3(28) = Vector3f(-fRadius, -fRadius, fRadius);
	m_pkVBuffer->Position3(29) = Vector3f(fRadius, -fRadius, fRadius);
	if (bHasNormal)
	{
		for (int i = 24; i < 30; i++)
		{
			m_pkVBuffer->Normal3(i) = Vector3f(0.0f, 0.0f, 1.0f);
		}
	}
	if (bHasTCoord)
	{
		m_pkVBuffer->TCoord2(0,24) = Vector2f(fRadius, 0.0f);
		m_pkVBuffer->TCoord2(0,25) = Vector2f(fRadius, fRadius);
		m_pkVBuffer->TCoord2(0,26) = Vector2f(0.0f, fRadius);
		m_pkVBuffer->TCoord2(0,27) = Vector2f(0.0f, fRadius);
		m_pkVBuffer->TCoord2(0,28) = Vector2f(0.0f, 0.0f);
		m_pkVBuffer->TCoord2(0,29) = Vector2f(fRadius, 0.0f);
	}

	// back
	m_pkVBuffer->Position3(30) = Vector3f(fRadius, -fRadius, -fRadius);
	m_pkVBuffer->Position3(31) = Vector3f(-fRadius, -fRadius, -fRadius);
	m_pkVBuffer->Position3(32) = Vector3f(-fRadius, fRadius, -fRadius);
	m_pkVBuffer->Position3(33) = Vector3f(-fRadius, fRadius, -fRadius);
	m_pkVBuffer->Position3(34) = Vector3f(fRadius, fRadius, -fRadius);
	m_pkVBuffer->Position3(35) = Vector3f(fRadius, -fRadius, -fRadius);
	if (bHasNormal)
	{
		for (int i = 30; i < 36; i++)
		{
			m_pkVBuffer->Normal3(i) = Vector3f(0.0f, 0.0f, -1.0f);
		}
	}
	if (bHasTCoord)
	{
		m_pkVBuffer->TCoord2(0,30) = Vector2f(fRadius, 0.0f);
		m_pkVBuffer->TCoord2(0,31) = Vector2f(0.0f, 0.0f);
		m_pkVBuffer->TCoord2(0,32) = Vector2f(0.0f, fRadius);
		m_pkVBuffer->TCoord2(0,33) = Vector2f(0.0f, fRadius);
		m_pkVBuffer->TCoord2(0,34) = Vector2f(fRadius, fRadius);
		m_pkVBuffer->TCoord2(0,35) = Vector2f(fRadius, 0.0f);
	}

	// set indexes
	int* aiIndex = m_pkIBuffer->GetData();
	for (int i = 0; i < 36; i++)
	{
		aiIndex[i] = i;
	}

	TriMesh* pkTriMesh = new TriMesh(m_pkVBuffer, m_pkIBuffer);
	return pkTriMesh;

}
//---------------------------------------------------------------------------------------------------
TriMesh* StandardMesh::Torus(float fMajorRadius, float fMinorRadius, int iNumMajor, int iNumMinor)
{

	// 6 vertices for 2 triangles. +1 to finish the circle(vertex[0] counts twice).
	m_iMaxVertex = iNumMajor * (iNumMinor+1) * 6;
	m_iNumIndexes = 0;
	m_iNumVertices = 0;

	m_pkVBuffer = new VertexBuffer(m_kAttr, m_iMaxVertex);
	m_pkIBuffer = new IndexBuffer(m_iMaxVertex);
	
	// construct a torus in xy plane.
	double dMajorSetp = 2.0 * Mathd::PI / iNumMajor;
	double dMinorSetp = 2.0 * Mathd::PI / iNumMinor;

	for (int i = 0; i < iNumMajor; i++)
	{
		double alpha0 = i * dMajorSetp;
		double alpha1 = alpha0 + dMajorSetp;
		float x0 = (float) cos(alpha0);
		float y0 = (float) sin(alpha0);
		float x1 = (float) cos(alpha1);
		float y1 = (float) sin(alpha1);

		Vector3f akVertex[4];
		Vector3f akNormal[4];
		Vector2f akTexture[4];

		for (int j = 0; j <= iNumMinor; j++)
		{
			double theta = j * dMinorSetp;
			float fInvMinorRadius = 1.0f / fMinorRadius;
			float c = (float)cos(theta);
			float fR = fMinorRadius * c + fMajorRadius;
			float fZ = fMinorRadius * (float)sin(theta);
			float t1 = (float)(j+1) / (float)iNumMinor;

			// vertex 0
			akVertex[0].X() = x0 * fR;
			akVertex[0].Y() = y0 * fR;
			akVertex[0].Z() = fZ;
			akNormal[0].X() = x0 * c;
			akNormal[0].Y() = y0 * c;
			akNormal[0].Z() = fZ * fInvMinorRadius;
			akNormal[0].Normalize();
			akTexture[0].X() = (float)i / (float)iNumMajor;
			akTexture[0].Y() = (float)j / (float)iNumMinor;

			// vertex 1
			akVertex[2].X() = x1 * fR;
			akVertex[2].Y() = y1 * fR;
			akVertex[2].Z() = fZ;
			akNormal[2].X() = x1 * c;
			akNormal[2].Y() = y1 * c;
			akNormal[2].Z() = fZ * fInvMinorRadius;
			akNormal[2].Normalize();
			akTexture[2].X() = (float)(i+1) / (float)iNumMajor;
			akTexture[2].Y() = (float)j / (float)iNumMinor;

			// next minor vertex
			theta = (j+1) * dMinorSetp;
			fInvMinorRadius = 1.0f / fMinorRadius;
			c = (float)cos(theta);
			fR = fMinorRadius * c + fMajorRadius;
			fZ = fMinorRadius * (float)sin(theta);

			// vertex 2
			akVertex[1].X() = x0 * fR;
			akVertex[1].Y() = y0 * fR;
			akVertex[1].Z() = fZ;
			akNormal[1].X() = x0 * c;
			akNormal[1].Y() = y0 * c;
			akNormal[1].Z() = fZ * fInvMinorRadius;
			akNormal[1].Normalize();
			akTexture[1].X() = (float)i / (float)iNumMajor;
			akTexture[1].Y() = t1;

			// vertex 3
			akVertex[3].X() = x1 * fR;
			akVertex[3].Y() = y1 * fR;
			akVertex[3].Z() = fZ;
			akNormal[3].X() = x1 * c;
			akNormal[3].Y() = y1 * c;
			akNormal[3].Z() = fZ * fInvMinorRadius;
			akNormal[3].Normalize();
			akTexture[3].X() = (float)(i+1) / (float)iNumMajor;
			akTexture[3].Y() = t1;

			AddTriangle(akVertex, akNormal, akTexture);

			// rearrange for next triangle
			memcpy(akVertex[0], akVertex[1], sizeof(Vector3f));
			memcpy(akNormal[0], akNormal[1], sizeof(Vector3f));
			memcpy(akTexture[0], akTexture[1], sizeof(Vector2f));

			memcpy(akVertex[1], akVertex[3], sizeof(Vector3f));
			memcpy(akNormal[1], akNormal[3], sizeof(Vector3f));
			memcpy(akTexture[1], akTexture[3], sizeof(Vector2f));

			AddTriangle(akVertex, akNormal, akTexture);
		}// end for minor
	}// end for major

	// send vbuffer and ibuffer into trimesh
	TriMesh* trimesh = new TriMesh(m_pkVBuffer, m_pkIBuffer);

	// release tmp buffer.
	delete m_pkVBuffer;
	delete m_pkIBuffer;
	m_pkVBuffer = 0;
	m_pkIBuffer = 0;

	return trimesh;
}
//---------------------------------------------------------------------------------------------------
TriMesh* StandardMesh::Sphere(float fRadius, int iSlices, int iStacks)
{
	float fdRho = Mathf::PI / (float)iStacks;
	float fdTheta = Mathf::TWO_PI / (float)iSlices;
	float fdS = 1.0f / (float)iSlices;
	float fdT = 1.0f / (float)iStacks;
	float fS = 0.0f;
	float fT = 1.0f;
	int i, j;

	m_iMaxVertex = iSlices * iStacks * 6;
	m_iNumIndexes = 0;
	m_iNumVertices = 0;

	m_pkVBuffer = new VertexBuffer(m_kAttr, m_iMaxVertex);
	m_pkIBuffer = new IndexBuffer(m_iMaxVertex);

	for (i = 0; i < iStacks; i++)
	{
		float fRho = (float)i * fdRho;
		float sinRho = (float)sin(fRho);
		float cosRho = (float)cos(fRho);
		float sinRhodRho = (float)sin(fRho + fdRho);
		float cosRhodRho = (float)cos(fRho + fdRho);

		fS = 0.0f;
		Vector3f kV[4];
		Vector3f kN[4];
		Vector2f kT[4];

		for (j = 0; j < iSlices; j++)
		{
			float fTheta = (j == iSlices) ? 0.0f : j * fdTheta;
			float sinTheta = (float)(-sin(fTheta));
			float cosTheta = (float)(cos(fTheta));

			float x = sinTheta * sinRho;
			float y = cosTheta * sinRho;
			float z = cosRho;
			Vector3f kn(x,y,z);
			kV[0] = fRadius * kn;
			kN[0] = kn;
			kT[0].X() = fS;
			kT[0].Y() = fT;

			kn.X() = sinTheta * sinRhodRho;
			kn.Y() = cosTheta * sinRhodRho;
			kn.Z() = cosRhodRho;
			kV[2] = fRadius * kn;
			kN[2] = kn;
			kT[2].X() = fS;
			kT[2].Y() = fT - fdT;

			fTheta = (j + 1 == iSlices) ? 0.0f : (j + 1) * fdTheta;
			sinTheta = (float)(-sin(fTheta));
			cosTheta = (float)(cos(fTheta));
			fS += fdS;

			kn.X() = sinTheta * sinRho;
			kn.Y() = cosTheta * sinRho;
			kn.Z() = cosRho;
			kV[1] = fRadius * kn;
			kN[1] = kn;
			kT[1].X() = fS;
			kT[1].Y() = fT;

			kn.X() = sinTheta * sinRhodRho;
			kn.Y() = cosTheta * sinRhodRho;
			kn.Z() = cosRhodRho;
			kV[3] = fRadius * kn;
			kN[3] = kn;
			kT[3].X() = fS;
			kT[3].Y() = fT - fdT;

			AddTriangle(kV, kN, kT);

			// rearrange for next triangle
			memcpy(kV[0], kV[1], sizeof(Vector3f));
			memcpy(kN[0], kN[1], sizeof(Vector3f));
			memcpy(kT[0], kT[1], sizeof(Vector2f));

			memcpy(kV[1], kV[3], sizeof(Vector3f));
			memcpy(kN[1], kN[3], sizeof(Vector3f));
			memcpy(kT[1], kT[3], sizeof(Vector2f));

			AddTriangle(kV, kN, kT);
		}
		fT -= fdT;
	}// end for

	// send vbuffer and ibuffer into trimesh
	TriMesh* trimesh = new TriMesh(m_pkVBuffer, m_pkIBuffer);
	// release tmp buffer.
	delete m_pkVBuffer;
	delete m_pkIBuffer;
	m_pkVBuffer = 0;
	m_pkIBuffer = 0;

	return trimesh;
}
//---------------------------------------------------------------------------------------------------
TriMesh* StandardMesh::Rectangle(int iXSamples, int iYSamples, float fXExtent, float fYExtent)
{
	int iVQuantity = iXSamples * iYSamples;
	int iTQuantity = 2 * (iXSamples - 1) * (iYSamples - 1);
	m_pkVBuffer = new VertexBuffer(m_kAttr, iVQuantity);
	m_pkIBuffer = new IndexBuffer(3 * iTQuantity);
	m_iNumVertices = iVQuantity;
	m_iNumIndexes = iTQuantity * 3;

	float fInv0 = 1.0f / (iXSamples - 1.0f);
	float fInv1 = 1.0f / (iYSamples - 1.0f);
	float fU, fV;
	int i, i0, i1;
	for (i1 = 0, i = 0; i1 < iYSamples; i1++)
	{
		fV = i1 * fInv1;
		Vector3f kYTmp = ((2.0f * fV - 1.0f) * fYExtent) * Vector3f::UNIT_Y;
		for (i0 = 0; i0 < iXSamples; i0++)
		{
			fU = i0 * fInv0;
            Vector3f kXTmp = ((2.0f * fU - 1.0f) * fXExtent) * Vector3f::UNIT_X;
			m_pkVBuffer->Position3(i) = kXTmp + kYTmp;
	

			if (m_kAttr.HasNormal())
			{
				m_pkVBuffer->Normal3(i) = -Vector3f::UNIT_Z;
			}

			if (m_kAttr.GetMaxTCoords() > 0)
			{
				Vector2f kTCoord(fU, fV);
				for (int iUnit = 0; iUnit < m_kAttr.GetMaxTCoords(); iUnit++)
				{
					if (m_kAttr.HasTCoord(iUnit))
					{
						m_pkVBuffer->TCoord2(iUnit, i) = kTCoord;
					}
				}
	
			}

			i++;
		}
	}

	// set index buffer
	int* aiIndex = m_pkIBuffer->GetData();
    for (i1 = 0, i = 0; i1 < iYSamples - 1; i1++)
    {
        for (i0 = 0; i0 < iXSamples - 1; i0++)
        {
            int iV0 = i0 + iXSamples * i1;
            int iV1 = iV0 + 1;
            int iV2 = iV1 + iXSamples;
            int iV3 = iV0 + iXSamples;
            aiIndex[i++] = iV0;
            aiIndex[i++] = iV1;
            aiIndex[i++] = iV2;
            aiIndex[i++] = iV0;
            aiIndex[i++] = iV2;
            aiIndex[i++] = iV3;
        }
    }

	TransformData(m_pkVBuffer);
	TriMesh* pkMesh = new TriMesh(m_pkVBuffer, m_pkIBuffer);
	return pkMesh;
}
//---------------------------------------------------------------------------------------------------
TriMesh* StandardMesh::RectangleTex(int iXPos, int iYPos, int iWidth, int iHeight)
{
	// rectangle used for rect texture
	m_pkVBuffer = new VertexBuffer(m_kAttr, 4);
	m_pkIBuffer = new IndexBuffer(6);

	float fXPos = (float)iXPos;
	float fYPos = (float)iYPos;
	float fWidth = (float)iWidth;
	float fHeight = (float)iHeight;
	// upper left
	m_pkVBuffer->Position3(0) = Vector3f(fXPos, fYPos, 0.0f);
	m_pkVBuffer->TCoord2(0,0) = Vector2f(0.0f, fHeight);

	// lower left
	m_pkVBuffer->Position3(1) = Vector3f(fXPos, fYPos - fHeight, 0.0f);
	m_pkVBuffer->TCoord2(0,1) = Vector2f(0.0f, 0.0f);

	// lower right
	m_pkVBuffer->Position3(2) = Vector3f(fXPos + iWidth, fYPos - fHeight, 0.0f);
	m_pkVBuffer->TCoord2(0,2) = Vector2f(fWidth, 0.0f);

	// upper right
	m_pkVBuffer->Position3(3) = Vector3f(fXPos + iWidth, fYPos, 0.0f);
	m_pkVBuffer->TCoord2(0,3) = Vector2f(fWidth, fHeight);

	// set indexes
	int* aiIndex = m_pkIBuffer->GetData();
	aiIndex[0] = 0;
	aiIndex[1] = 1;
	aiIndex[2] = 3;
	aiIndex[3] = 1;
	aiIndex[4] = 2;
	aiIndex[5] = 3;

	TriMesh* pkTriMesh = new TriMesh(m_pkVBuffer, m_pkIBuffer);
	return pkTriMesh;

}
//---------------------------------------------------------------------------------------------------
void StandardMesh::AddTriangle(Vector3f* akV, Vector3f* akN, Vector2f* akT)
{
	// Add a triangle to the mesh. This searches the current list for identical
	// (well, almost identical - these are floats you know...) verts. If one is found, it
	// is added to the index array. If not, it is added to both the index array and the vertex
	// array grows by one as well.
	int* aiIndex = m_pkIBuffer->GetData();
	
	for (int i = 0; i < 3; i++)
	{
		int iVertex = IsExist(akV[i], akN[i], akT[i]);
		if ( iVertex != -1)
		{
			// already in the vertex list, add index only
			aiIndex[m_iNumIndexes] = iVertex;
			m_iNumIndexes++;
		}
		else
		{
			// not in the list, add it
			if (m_iNumVertices > m_iMaxVertex || m_iNumIndexes > m_iMaxVertex)
			{
				System::MsgBoxPrintf(RP2_ERROR, TC("Vertices overflow when creating mesh."));
				break;
			}
			memcpy(m_pkVBuffer->PositionTuple(m_iNumVertices), akV[i], sizeof(Vector3f));
			if (m_pkVBuffer->HasNormal())
			{
				memcpy(m_pkVBuffer->NormalTuple(m_iNumVertices), akN[i], sizeof(Vector3f));
			}
			if (m_pkVBuffer->HasTCoord(0))
			{
				memcpy(m_pkVBuffer->TCoordTuple(0, m_iNumVertices), akT[i], sizeof(Vector2f));
			}

			
			aiIndex[m_iNumIndexes] = m_iNumVertices;
			m_iNumVertices++;
			m_iNumIndexes++;
		}
	}
}
//---------------------------------------------------------------------------------------------------
int StandardMesh::IsExist(const Vector3f& rkV, const Vector3f& rkN, const Vector2f& rkT)
{
	for (int i = 0; i < m_iNumVertices; i++)
	{
		if (rkV.SameAs(m_pkVBuffer->Position3(i))
			&& rkN.SameAs(m_pkVBuffer->Normal3(i))
			&& rkT.SameAs(m_pkVBuffer->TCoord2(0,i)))
		{
			return i;
		}
	}
	return -1;
}
//---------------------------------------------------------------------------------------------------
int StandardMesh::GetNumVertices()
{
	return m_iNumVertices;
}
//---------------------------------------------------------------------------------------------------
void StandardMesh::TransformData(VertexBuffer* pkVB)
{
    if (m_kXFrm.IsIdentity())
    {
        return;
    }

    int iVQuantity = pkVB->GetVQuantity();
    int i;
    for (i = 0; i < iVQuantity; i++)
    {
        pkVB->Position3(i) = m_kXFrm.ApplyForward(pkVB->Position3(i));
    }

    if (m_kAttr.HasNormal())
    {
        Vector3f kSave = m_kXFrm.GetTranslate();
        m_kXFrm.SetTranslate(Vector3f::ZERO);
        for (i = 0; i < iVQuantity; i++)
        {
            pkVB->Normal3(i) = m_kXFrm.ApplyForward(pkVB->Normal3(i));
            pkVB->Normal3(i).Normalize();
        }
        m_kXFrm.SetTranslate(kSave);
    }	
}
//---------------------------------------------------------------------------------------------------
